Skip to main content

Object-oriented Programming

Object-Oriented Programming (OOP) is a programming paradigm that uses "objects" to design software. It allows developers to create classes that encapsulate data and functions, promoting code reusability and modularity.

Key Concepts

  • Classes and Objects: A class is a blueprint for creating objects (instances), providing initial values for state (attributes) and implementations of behavior (methods).
  • Attributes: Variables that belong to an instance or class.
  • Methods: Functions defined within a class that describe the behaviors of an object.

What Is a Method?

Methods are functions associated with object parameters that modify the state of that object. They are essential for defining the behaviors of an object and can be categorized into:

Instance Methods

Instance methods are the most common type of methods in Python:

  • Defined within a class and operate on instances of that class.
  • The first parameter is always self, representing the instance.
  • Can access and modify instance attributes.
class Apple:
def __init__(self, color, flavor):
self.color = color
self.flavor = flavor

def description(self):
return f"This apple is {self.color} and tastes {self.flavor}."

Usage:

jonagold = Apple("red", "sweet")
print(jonagold.description())
# Output: This apple is red and tastes sweet.

Class Methods

Class methods are called on the class itself, not on instances:

  • Use the @classmethod decorator.
  • The first parameter is cls, representing the class.
  • Commonly used for factory methods or to modify class state.
class Fruit:
count = 0

@classmethod
def increase_count(cls):
cls.count += 1

Static Methods

Static methods are utility functions within a class:

  • Use the @staticmethod decorator.
  • Do not take self or cls as a parameter.
  • Behave like regular functions but reside within the class's namespace.
class MathUtils:
@staticmethod
def add(a, b):
return a + b

Choosing a Method Type

  • Instance Methods: When you need to access or modify instance-specific data.
  • Class Methods: When you need to access or modify class-level data.
  • Static Methods: When you need a utility function that doesn't access instance or class data.

Constructors and Special Methods

The Constructor: __init__

The constructor method __init__ initializes an object's attributes upon creation:

class Apple:
def __init__(self, color="red", flavor="sweet"):
self.color = color
self.flavor = flavor

Usage:

honeycrisp = Apple("green", "tart")
print(honeycrisp.color)
# Output: green

Other Special Methods

Special methods in Python start and end with double underscores (__), known as dunder methods. They allow objects to interact with Python's built-in functions and operators.

Common Dunder Methods

  • __str__(self): Defines the string representation of the object for print() and str().

    class Apple:
    def __str__(self):
    return f"This apple is {self.color} and tastes {self.flavor}."

    Usage:

    print(honeycrisp)
    # Output: This apple is green and tastes tart.
  • __len__(self): Returns the length of the object.

  • __eq__(self, other): Defines equality comparison between two objects.

Example: Custom String Representation

class Piglet:
def __init__(self, name="Piglet"):
self.name = name

def __str__(self):
return f"Oink! I'm {self.name}!"

hamlet = Piglet("Hamlet")
print(hamlet)
# Output: Oink! I'm Hamlet!

Special Methods as Operators

Python allows you to define or override the behavior of operators using special methods.

Overriding Operators

  • Arithmetic Operators: __add__, __sub__, __mul__, __truediv__, etc.
  • Comparison Operators: __eq__, __lt__, __gt__, etc.

Example: Overriding the Addition Operator

class Triangle:
def __init__(self, base, height):
self.base = base
self.height = height

def area(self):
return 0.5 * self.base * self.height

def __add__(self, other):
return self.area() + other.area()

triangle1 = Triangle(10, 5)
triangle2 = Triangle(6, 8)

print(f"Triangle 1 area: {triangle1.area()}")
print(f"Triangle 2 area: {triangle2.area()}")
print(f"Combined area: {triangle1 + triangle2}")
# Output:
# Triangle 1 area: 25.0
# Triangle 2 area: 24.0
# Combined area: 49.0

For a full list of operator methods, refer to Python's operator module.

Instance Methods in Depth

Instance methods are crucial for defining the behaviors of objects.

Defining and Using Instance Methods

class Piglet:
name = "Piglet"

def speak(self):
print(f"Oink! I'm {self.name}!")

def pig_years(self):
return self.age * 18

hamlet = Piglet()
hamlet.name = "Hamlet"
hamlet.age = 2
hamlet.speak()
# Output: Oink! I'm Hamlet!
print(hamlet.pig_years())
# Output: 36
  • Instance Variables: Variables unique to each instance.
  • Methods: Can perform actions and return values.

Key Takeaways

  • Encapsulation: Classes encapsulate data and behaviors.
  • Reusability: Promotes code reuse and organization.
  • Flexibility: Special methods allow customization of object interactions.